從七月開始從零開始研究PySide2 GUI相關設計及程式如何撰寫,已經有一段時間了,筆者深深有感,PySide 系列的水很深。
Let's GO ~~
如何把獲取以下項目的文字
下拉式選單self.ui.[opt].currentText()
LineEditself.ui.[opt].text()
spinboxself.ui.[opt].text()
[筆記]
下拉式選單的進階應用, 選擇選單中的任何項目,均得到不同的回應
以常見的UART (Serial Port)的連線設定為例
作法:
Pari = {'None': "serial.PARITY_NONE", 'Even': "serial.PARITY_EVEN", 'Odd': "serial.PARITY_ODD",
'Mark': "serial.PARITY_MARK", 'Space': "serial.PARITY_SPACE"}
fc = {"None": [False, False, False], "XON/ XOFF": [True, False, False], "RTS/CTS": [False, True, False],
"XON/ XOFF & RTS/CTS": [True, True, False],
"DTR/DSR": [False, False, True], "XON/ XOFF & DTR/DSR": [True, False, True]}
def getdValue(self, whichDict, target):
if debug:
print(target, whichDict)
for key, value in eval(whichDict).items():
if key == target:
return value
fxopt = ["'COM{0}'".format(self.ui.le_eqComID.text()),
int(self.ui.spb_eqBaudRate.text()), int(self.ui.le_eqDatabit.text()),
self.fn.getdictValue("pari", self.ui.cb_eqParity.currentText()),
int(self.ui.le_eqStopbit.text()),
float(self.ui.le_eqTimeout.text()) / 1000,
self.getdValue("fc",
self.ui.cb_eqFlowControl.currentText()),
]
作法:
def out(self, edit, message):
"""(edit, msg) Write any message to any textbox.
edit: any Textbox label , e.g txtbox_logs
msg: any message
"""
export = eval("self.ui.{0}".format(edit))
export.moveCursor(QtGui.QTextCursor.End)
export.insertPlainText("{0} {1}\r\n".format(self.fn.currDate(), message))
簡單的說就是要使用thread 去切開使用
作法:
from PySide2.QtWidgets import QApplication, QMainWindow, QMessageBox, QWidget, QCheckBox
from PySide2 import QtGui, QtCore
from PySide2.QtCore import QThread, Signal, QObject, QEvent, Qt
class MainWindow(QMainWindow):
def __init__(self):
super(MainWindow, self).__init__()
self.ui = Ui_MainWindow()
self.ui.setupUi(self)
.....
.....
def runTasks(self):
self.Transmitter = from()
self.thread1 = QThread()
self.thread1.started.connect(self.Into.work)
self.Transmitter.from.connect(self.from)
self.Transmitter.finished.connect(self.Loop_finished)
self.Transmitter.finished.connect(self.thread1.quit)
self.Transmitter.finished.connect(self.Transmitter.deleteLater)
self.thread1.finished.connect(self.thread1.deleteLater)
self.Transmitter.moveToThread(self.thread1)
self.thread1.start()
def from(self, values):
self.ui.txtbox_tx.clear()
self.ui.txtbox_tx.moveCursor(QtGui.QTextCursor.End)
self.ui.txtbox_tx.insertPlainText(values + "\r\n")
def Loop_finished(self):
print("Into Loop: Offline")
print("From Loop: Offline")
class from(QObject):
finished = Signal()
from = Signal(str)
@QtCore.Slot()
def __init__(self):
super(Receiver, self).__init__()
self.working = True
self.checkTime = 0
def work(self):
answer = answer + 100
while True:
self.from.emit(autoAnswer)
time.sleep(0.2)
if answer > 2000:
break
self.finished.emit()
使用event handler 偵測鍵盤事件,但筆者想要做的是當某個區域被觸發後鍵盤事件才會開始偵測。
會這麼設計的原因是,不想要UI一執行的時候就占用大量資源,反而是需要用的時候再啟用相關功能就好了
未來在維護上也會相對簡單許多
作法:
效果:
class MainWindow(QMainWindow):
def __init__(self):
...
...
self.ui.btn_conExit.clicked.connect(lambda: self.exitSingleMode())
self.ui.btnSingle.clicked.connect(lambda: self.singleMode())
def singleMode(self):
self.ui.grpObj_SingleMode.setEnabled(True)
self.ui.cmdline.installEventFilter(self)
self.ui.btn_single.setEnabled(False)
def exitSingleMode(self):
self.ui.btn_single.setEnabled(True)
self.ui.grpObj_SingleMode.setEnabled(False)
self.ui.cmdline.removeEventFilter(self)
結論:
基本上筆者整理的資料,是以簡單的template為主,很多詳細說明是刻意沒寫出來的,因為筆者需要的很多未來可以使用到的範例。讓未來的自己可以直接複製貼上再改點變數就可以直接套用的。或者是可以把這些範本直接寫入code snippet中當作未來的參考